package cn.wuxing.mediation.infoconfig.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.wuxing.mediation.common.constant.UserConstants;
import cn.wuxing.mediation.common.core.domain.CommitteeUserVO;
import cn.wuxing.mediation.common.core.domain.TreeSelect;
import cn.wuxing.mediation.common.core.domain.entity.IcMediatorCommittee;
import cn.wuxing.mediation.common.core.domain.entity.IcUserCommittee;
import cn.wuxing.mediation.common.core.text.Convert;
import cn.wuxing.mediation.common.exception.ServiceException;
import cn.wuxing.mediation.common.utils.SecurityUtils;
import cn.wuxing.mediation.common.utils.StringUtils;
import cn.wuxing.mediation.common.utils.spring.SpringUtils;
import cn.wuxing.mediation.infoconfig.domain.dto.AddMediatorCommitteeUserDTO;
import cn.wuxing.mediation.infoconfig.domain.dto.RemoveMediatorCommitteeUserDTO;
import cn.wuxing.mediation.infoconfig.domain.vo.MediatorCommitteeUserVO;
import cn.wuxing.mediation.infoconfig.mapper.IcMediatorCommitteeMapper;
import cn.wuxing.mediation.infoconfig.mapper.IcUserCommitteeMapper;
import cn.wuxing.mediation.infoconfig.mapper.IcUserWindowMapper;
import cn.wuxing.mediation.infoconfig.service.IIcMediatorCommitteeService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 调解委员会管理 服务实现
 *
 * @author mediation
 */
@Service
public class IcMediatorCommitteeServiceImpl implements IIcMediatorCommitteeService {

    @Autowired
    private IcMediatorCommitteeMapper icMediatorCommitteeMapper;

    @Autowired
    private IcUserCommitteeMapper icUserCommitteeMapper;

    @Autowired
    private IcUserWindowMapper icUserWindowMapper;

    /**
     * 查询调解委员会管理数据
     *
     * @param icMediatorCommittee 调解委员会信息
     * @return 调解委员会信息集合
     */
    @Override
    public List<IcMediatorCommittee> selectMediatorCommitteeList(IcMediatorCommittee icMediatorCommittee) {
        return icMediatorCommitteeMapper.selectMediatorCommitteeList(icMediatorCommittee);
    }

    /**
     * 查询调解委员会树结构信息
     *
     * @param icMediatorCommittee 调解委员会信息
     * @return 调解委员会树信息集合
     */
    @Override
    public List<TreeSelect> selectMediatorCommitteeTreeList(IcMediatorCommittee icMediatorCommittee) {
        List<IcMediatorCommittee> list = this.icMediatorCommitteeMapper.selectMediatorCommitteeList(icMediatorCommittee);
        return buildMediatorCommitteeTreeSelect(list);
    }

    @Override
    public List<TreeSelect> selectMediatorCommitteeTreeDropDown(IcMediatorCommittee icMediatorCommittee) {
        List<Long> windowIds = null;
        if (null != SecurityUtils.getUserId()) {
            if (!Long.valueOf(1L).equals(SecurityUtils.getUserId())) {
                windowIds = this.icUserWindowMapper.getWindowIdList(SecurityUtils.getUserId());
            }
        }

        List<IcMediatorCommittee> list = this.icMediatorCommitteeMapper.selectMediatorCommitteeListByWindow(icMediatorCommittee, windowIds);
        if (CollUtil.isEmpty(list)) {
            return new LinkedList<>();
        }
        List<Long> committeeIds = list.stream().map(IcMediatorCommittee::getId).collect(Collectors.toList());
        List<TreeSelect> treeSelects = buildMediatorCommitteeTreeSelect(list);

        List<CommitteeUserVO> users = icUserCommitteeMapper.selectUserByCommitteeId(committeeIds);
        if (CollUtil.isEmpty(users)) {
            return treeSelects;
        }

        Map<Long, List<CommitteeUserVO>> userMap = users.stream()
                .collect(Collectors.groupingBy(CommitteeUserVO::getCommitteeId));

        this.setUserToMediatorCommittee(treeSelects, userMap);


        return treeSelects;
    }

    /**
     * 构建前端所需要树结构
     *
     * @param committees 调解委员会列表
     * @return 树结构列表
     */
    @Override
    public List<IcMediatorCommittee> buildMediatorCommitteeTree(List<IcMediatorCommittee> committees) {
        List<IcMediatorCommittee> returnList = new ArrayList<IcMediatorCommittee>();
        List<Long> tempList = committees.stream().map(IcMediatorCommittee::getId).collect(Collectors.toList());
        for (IcMediatorCommittee committee : committees) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(committee.getParentId())) {
                recursionFn(committees, committee);
                returnList.add(committee);
            }
        }
        if (returnList.isEmpty()) {
            returnList = committees;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param icMediatorCommittees 调解委员会列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildMediatorCommitteeTreeSelect(List<IcMediatorCommittee> icMediatorCommittees) {
        List<IcMediatorCommittee> trees = buildMediatorCommitteeTree(icMediatorCommittees);
        return trees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 根据调解委员会ID查询信息
     *
     * @param id 调解委员会ID
     * @return 调解委员会信息
     */
    @Override
    public IcMediatorCommittee selectCommitteeById(Long id) {
        return icMediatorCommitteeMapper.selectMediatorCommitteeById(id);
    }

    /**
     * 根据ID查询所有子调解委员会（正常状态）
     *
     * @param id 调解委员会ID
     * @return 子调解委员会数
     */
    @Override
    public int selectNormalChildrenById(Long id) {
        return icMediatorCommitteeMapper.selectNormalChildrenById(id);
    }

    /**
     * 是否存在子节点
     *
     * @param id 调解委员会ID
     * @return 结果
     */
    @Override
    public boolean hasChildById(Long id) {
        int result = icMediatorCommitteeMapper.hasChildById(id);
        return result > 0;
    }

    /**
     * 查询调解委员会是否存在用户
     *
     * @param dto 调解委员会ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkMediatorCommitteeExistUser(AddMediatorCommitteeUserDTO dto) {
        int result = icMediatorCommitteeMapper.checkMediatorCommitteeExistUser(dto);
        return result > 0;
    }

    /**
     * 校验调解委员会名称是否唯一
     *
     * @param icMediatorCommittee 信息
     * @return 结果
     */
    @Override
    public boolean checkCommitteeNameUnique(IcMediatorCommittee icMediatorCommittee) {
        Long id = StringUtils.isNull(icMediatorCommittee.getId()) ? -1L : icMediatorCommittee.getId();
        IcMediatorCommittee info = icMediatorCommitteeMapper.checkMediatorCommitteeNameUnique(
                icMediatorCommittee.getMediatorCommitteeName(), icMediatorCommittee.getParentId());
        if (StringUtils.isNotNull(info) && info.getId().equals(id)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }


    /**
     * 新增保存调解委员会信息
     *
     * @param  icMediatorCommittee 调解委员会信息
     * @return 结果
     */
    @Override
    public int insertMediatorCommittee(IcMediatorCommittee icMediatorCommittee) {
        IcMediatorCommittee info = icMediatorCommitteeMapper.selectMediatorCommitteeById(
                icMediatorCommittee.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (null != info && !UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
            throw new ServiceException("调解委员会停用，不允许新增");
        }

        String ancestors;
        if (null == info) {
            ancestors = "0";
        }else {
            ancestors = info.getAncestors() + "," + icMediatorCommittee.getParentId();
        }

        icMediatorCommittee.setAncestors(ancestors);
        return icMediatorCommitteeMapper.insertIcMediatorCommittee(icMediatorCommittee);
    }

    /**
     * 修改保存调解委员会信息
     *
     * @param icMediatorCommittee 调解委员会信息
     * @return 结果
     */
    @Override
    public int updateMediatorCommittee(IcMediatorCommittee icMediatorCommittee) {
        IcMediatorCommittee newParentCommittee = icMediatorCommitteeMapper.selectMediatorCommitteeById(
                icMediatorCommittee.getParentId());
        IcMediatorCommittee oldCommittee = icMediatorCommitteeMapper.selectMediatorCommitteeById(
                icMediatorCommittee.getId());
        if (StringUtils.isNotNull(newParentCommittee) && StringUtils.isNotNull(oldCommittee)) {
            String newAncestors = newParentCommittee.getAncestors() + "," + newParentCommittee.getId();
            String oldAncestors = oldCommittee.getAncestors();
            icMediatorCommittee.setAncestors(newAncestors);
            updateCommitteeChildren(icMediatorCommittee.getId(), newAncestors, oldAncestors);
        }
        int result = icMediatorCommitteeMapper.updateMediatorCommittee(icMediatorCommittee);
        if (UserConstants.DEPT_NORMAL.equals(icMediatorCommittee.getStatus()) && StringUtils.isNotEmpty(
                icMediatorCommittee.getAncestors())
                && !StringUtils.equals("0", icMediatorCommittee.getAncestors())) {
            // 如果该调解委员会是启用状态，则启用该调解委员会的所有上级调解委员会
            updateParentMediatorCommitteeStatusNormal(icMediatorCommittee);
        }
        return result;
    }

    /**
     * 删除调解委员会管理信息
     *
     * @param id 调解委员会ID
     * @return 结果
     */
    @Override
    public int deleteById(Long id) {
        return icMediatorCommitteeMapper.delById(id);
    }

    @Override
    public List<MediatorCommitteeUserVO> getMediatorCommitteeUserList(String name, Long mediatorCommitteeId) {
        return this.icMediatorCommitteeMapper.getMediatorCommitteeUserList(name, mediatorCommitteeId);
    }

    @Override
    public void addMediatorCommitteeUser(AddMediatorCommitteeUserDTO dto) {

        dto.getUserIdList().forEach(i -> {
            if (StringUtils.isBlank(i)) {
                return;
            }
            IcUserCommittee icUserCommittee = new IcUserCommittee();
            icUserCommittee.setMediatorCommitteeId(dto.getMediatorCommitteeId());
            icUserCommittee.setUserId(Long.parseLong(i));
            icUserCommittee.setCreateBy(SecurityUtils.getLoginUser().getUsername());
            icUserCommittee.setCreateTime(DateTime.now());
            this.icUserCommitteeMapper.insert(icUserCommittee);
        });
    }

    @Override
    public void removeMediatorCommitteeUser(RemoveMediatorCommitteeUserDTO dto) {
        this.icUserCommitteeMapper.delete(Wrappers.<IcUserCommittee>lambdaQuery()
                .eq(IcUserCommittee::getUserId, dto.getUserId())
                .eq(IcUserCommittee::getMediatorCommitteeId, dto.getMediatorCommitteeId()));
    }

    @Override
    public String getMediatorCommitteeName(Long mediatorCommitteeId) {
        if (null == mediatorCommitteeId) {
            return null;
        }
        IcMediatorCommittee icMediatorCommittee = this.selectCommitteeById(mediatorCommitteeId);
        if (null == icMediatorCommittee) {
            return null;
        }

        List<Long> ids = new LinkedList<>();
        List<String> names = new LinkedList<>();
        ids.add(mediatorCommitteeId);
        names.add(icMediatorCommittee.getMediatorCommitteeName());
        this.getName(String.valueOf(mediatorCommitteeId), ids, names);
        Collections.reverse(ids);
        Collections.reverse(names);
        return StringUtils.getStringByList(names, "/");
    }
    private void getName(String id, List<Long> ids, List<String> names) {
        if (null == id) {
            return;
        }
        IcMediatorCommittee icMediatorCommittee = this.selectCommitteeById(Long.parseLong(id));
        if (null == icMediatorCommittee || null == icMediatorCommittee.getParentId()) {
            return;
        }
        ids.add(icMediatorCommittee.getParentId());
        IcMediatorCommittee pMediatorCommittee = this.selectCommitteeById(icMediatorCommittee.getParentId());
        if (null == pMediatorCommittee) {
            return;
        }
        names.add(pMediatorCommittee.getMediatorCommitteeName());
        this.getName(String.valueOf(icMediatorCommittee.getParentId()), ids, names);
    }

    /**
     * 修改该调解委员会的父级调解委员会状态
     *
     * @param icMediatorCommittee 当前调解委员会
     */
    private void updateParentMediatorCommitteeStatusNormal(IcMediatorCommittee icMediatorCommittee) {
        String ancestors = icMediatorCommittee.getAncestors();
        Long[] ids = Convert.toLongArray(ancestors);
        icMediatorCommitteeMapper.updateMediatorCommitteeStatusNormal(ids);
    }

    /**
     * 修改子元素关系
     *
     * @param id 被修改的调解委员会ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateCommitteeChildren(Long id, String newAncestors, String oldAncestors) {
        List<IcMediatorCommittee> children = icMediatorCommitteeMapper.selectChildrenById(id);
        for (IcMediatorCommittee child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (!children.isEmpty()) {
            icMediatorCommitteeMapper.updateChildren(children);
        }
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<IcMediatorCommittee> list, IcMediatorCommittee t) {
        // 得到子节点列表
        List<IcMediatorCommittee> childList = getChildList(list, t);
        t.setChildren(childList);
        for (IcMediatorCommittee tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<IcMediatorCommittee> getChildList(List<IcMediatorCommittee> list, IcMediatorCommittee t) {
        List<IcMediatorCommittee> tlist = new ArrayList<IcMediatorCommittee>();
        Iterator<IcMediatorCommittee> it = list.iterator();
        while (it.hasNext()) {
            IcMediatorCommittee n = (IcMediatorCommittee) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<IcMediatorCommittee> list, IcMediatorCommittee t) {
        return getChildList(list, t).size() > 0;
    }

    private void setUserToMediatorCommittee(List<TreeSelect> treeSelects, Map<Long, List<CommitteeUserVO>> userMap){

        for (TreeSelect treeSelect : treeSelects) {

            List<CommitteeUserVO> userList = userMap.get(treeSelect.getId());
            if (CollUtil.isNotEmpty(userList)) {
                treeSelect.setUsers(userList);
            }
            if (CollUtil.isNotEmpty(treeSelect.getChildren())) {
                this.setUserToMediatorCommittee(treeSelect.getChildren(), userMap);
            }
        }
    }
}
